#ifndef AVALON_SERVICELOCATORSERVICES_HPP
#define AVALON_SERVICELOCATORSERVICES_HPP
#include "Avalon/ServiceLocator/Directory.hpp"
#include "Avalon/ServiceLocator/DirectoryEntry.hpp"
#include "Avalon/ServiceLocator/ServiceEntry.hpp"
#include "Avalon/Services/Service.hpp"
#include "Avalon/Services/TupleMessage.hpp"

namespace Avalon {
namespace ServiceLocator {

  //! Returns an Account's session id.
  /*!
    \param accountId The id of the Account.
    \return A tuple with the following elements:
            0: <code>true</code> iff the operation succeeded.
            1: A message describing the result.
            2: The <i>accountId</i>'s session id.
  */
  AVALON_DECLARE_SERVICE(GetSessionIdService,
    "Avalon.ServiceLocator.GetSessionIdService",
    boost::tuple<bool, std::string, std::string>, unsigned int);

  //! Logs into the ServiceLocator.
  /*!
    \param username The Account's username.
    \param password The Account's password.
    \return A tuple with the following elements:
            0: <code>true</code> iff the Account logged in.
            1: A message describing the result.
            2: The Tag identifying the Account.
            3: The login's session id.
  */
  AVALON_DECLARE_SERVICE(LoginService, "Avalon.ServiceLocator.LoginService",
    boost::tuple<bool, std::string, DirectoryEntry::Tag, std::string>,
    std::string, std::string);

  //! Registers a service with the ServiceLocator.
  /*!
    \param name The name of the service to register.
    \param details The details of the service.
    \return A tuple with the following elements:
            0: <code>true</code> iff the service was registered.
            1: A message describing the result.
            2: The ServiceEntry that was registered.
  */
  AVALON_DECLARE_SERVICE(RegisterService,
    "Avalon.ServiceLocator.RegisterService",
    boost::tuple<bool, std::string, ServiceEntry>, std::string, std::string);

  //! Unregisters a service from the ServiceLocator.
  /*!
    \param id The id of the service to unregister.
    \return A tuple with the following elements:
            0: <code>true</code> iff the service was unregistered.
            1: A message describing the result.
  */
  AVALON_DECLARE_SERVICE(UnregisterService,
    "Avalon.ServiceLocator.UnregisterService",
    boost::tuple<bool, std::string>, int);

  //! Locates a service.
  /*!
    \param name The name of the service to locate.
    \return A tuple with the following elements:
            0: <code>true</code> iff the operation succeeded.
            1: A message describing the result.
            2: A list of ServiceEntry's for the service that was located.
  */
  AVALON_DECLARE_SERVICE(LocateService, "Avalon.ServiceLocator.LocateService",
    boost::tuple<bool, std::string, std::vector<ServiceEntry> >, std::string);

  //! Subscribes to notifications about the availability of a service.
  /*!
    \param name The name of the service to subscribe to.
    \return A tuple with the following elements:
            0: <code>true</code> iff the subscription was added.
            1: A message describing the result.
            2: A list of ServiceEntry's for the services currently available
               with the specified <i>name</i>.
  */
  AVALON_DECLARE_SERVICE(SubscribeAvailabilityService,
    "Avalon.ServiceLocator.SubscribeAvailabilityService",
    boost::tuple<bool, std::string, std::vector<ServiceEntry> >, std::string);

  //! Unsubscribes from notifications about the availability of a service.
  /*!
    \param name The name of the service to unsubscribe from.
    \return A tuple with the following elements:
            0: <code>true</code> iff the subscription was removed.
            1: A message describing the result.
  */
  AVALON_DECLARE_SERVICE(UnsubscribeAvailabilityService,
    "Avalon.ServiceLocator.UnsubscribeAvailabilityService",
    boost::tuple<bool, std::string>, std::string);

  //! Loads a DirectoryEntry's Tag.
  /*!
    \param id The id of the DirectoryEntry to load.
    \return A tuple with the following elements:
            0: <code>true</code> iff the DirectoryEntry was loaded.
            1: A message describing the result.
            2: The DirectoryEntry's Tag with the specified <i>id</i>.
  */
  AVALON_DECLARE_SERVICE(LoadDirectoryEntryService,
    "Avalon.ServiceLocator.LoadDirectoryEntryService",
    boost::tuple<bool, std::string, DirectoryEntry*>, unsigned int);
  AVALON_DECLARE_SERVICE(LoadParentDirectoryService,
    "Avalon.ServiceLocator.LoadParentDirectoryService",
    boost::tuple<bool, std::string, DirectoryEntry::Tag>, unsigned int);
  AVALON_DECLARE_SERVICE(CreateAccountService,
    "Avalon.ServiceLocator.CreateAccountService",
    boost::tuple<bool, std::string, DirectoryEntry::Tag>,
    std::string, DirectoryEntry::Tag, std::string);
  AVALON_DECLARE_SERVICE(CreateDirectoryService,
    "Avalon.ServiceLocator.CreateDirectoryService",
    boost::tuple<bool, std::string>, std::string, DirectoryEntry::Tag);
  AVALON_DECLARE_SERVICE(MoveEntryService,
    "Avalon.ServiceLocator.MoveEntryService", boost::tuple<bool, std::string>,
    unsigned int, unsigned int);
  AVALON_DECLARE_SERVICE(DeleteEntryService,
    "Avalon.ServiceLocator.DeleteEntryService",
    boost::tuple<bool, std::string>, unsigned int);
  AVALON_DECLARE_SERVICE(SetPermissionsService,
    "Avalon.ServiceLocator.SetPermissionsService",
    boost::tuple<bool, std::string>, unsigned int, unsigned int,
    Directory::Permission);
  AVALON_DECLARE_SERVICE(SessionAuthenticationService,
    "Avalon.ServiceLocator.SessionAuthenticationService",
    boost::tuple<bool, std::string, DirectoryEntry::Tag>, std::string,
    unsigned int);
  AVALON_DECLARE_MESSAGE(SessionAuthenticationMessage,
    "Avalon.ServiceLocator.SessionAuthenticationMessage", bool);
  AVALON_DECLARE_MESSAGE(ServiceAvailabilityMessage,
    "Avalon.ServiceLocator.ServiceAvailabilityMessage", ServiceEntry, bool);
  AVALON_DECLARE_MESSAGE(DirectoryEntryMovedMessage,
    "Avalon.ServiceLocator.DirectoryEntryMovedMessage", DirectoryEntry::Tag,
    DirectoryEntry::Tag, bool);
}
}

#endif // AVALON_SERVICELOCATORSERVICES_HPP
